﻿using AutoMapper;
using MediatR;
using RBAC.Domain.SmartHealthcare.Hosiptial;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using SmartHealthcare.Write.Api.Application.Command.InpatientRegistry;
using System.Transactions;

namespace SmartHealthcare.Write.Api.Application.Handler.InpatientRegistry
{
    /// <summary>
    /// 创建住院登记处理器
    /// </summary>
    public class CreateInpatientRegistryHandler : IRequestHandler<CreateInpatientRegistryCommand, APIResult<int>>
    {
        private readonly IBaseRepository<InpatientRegistryModel> inpatientRegistryRepository;
        private readonly IBaseRepository<HospitalBedModel> hospitalBedRepository;
        private readonly IBaseRepository<HospitalRoomModel> hospitalRoomRepository;
        private readonly IMapper mapper;
        private readonly ILogger<CreateInpatientRegistryHandler> logger;

        public CreateInpatientRegistryHandler(
            IBaseRepository<InpatientRegistryModel> inpatientRegistryRepository,
            IBaseRepository<HospitalBedModel> hospitalBedRepository,
            IBaseRepository<HospitalRoomModel> hospitalRoomRepository,
            IMapper mapper,
            ILogger<CreateInpatientRegistryHandler> logger)
        {
            this.inpatientRegistryRepository = inpatientRegistryRepository;
            this.hospitalBedRepository = hospitalBedRepository;
            this.hospitalRoomRepository = hospitalRoomRepository;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 创建住院登记
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<APIResult<int>> Handle(CreateInpatientRegistryCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> res = new APIResult<int>();

            try
            {
                logger.LogInformation($"开始创建住院登记，病人卡号:{request.MedicalCard}，科室ID:{request.DepartmentId}，病房ID:{request.WardNo}，病床ID:{request.WardId}");

                // 业务验证
                var validationResult = ValidateRequest(request);
                if (!validationResult.IsValid)
                {
                    res.Code = APIEnums.Fail;
                    res.Msg = validationResult.ErrorMessage;
                    logger.LogWarning($"住院登记创建失败，验证失败: {validationResult.ErrorMessage}");
                    return Task.FromResult(res);
                }

                using (TransactionScope transaction = new TransactionScope())
                {
                    try
                    {
                        // 1. 创建住院登记记录
                        var inpatientRegistry = new InpatientRegistryModel
                        {
                            MedicalCard = request.MedicalCard,
                            DepartmentId = request.DepartmentId,
                            WardNo = request.WardNo,
                            WardId = request.WardId,
                            AdvancePayment = request.AdvancePayment,
                            DiseaseDescription = request.DiseaseDescription,
                            DrugContraindications = request.DrugContraindications,
                            AdmissionTime = request.AdmissionTime ?? DateTime.Now,
                            Discharge_status = false // 默认未出院
                        };

                        var registryResult = inpatientRegistryRepository.Create(inpatientRegistry);
                        
                        if (registryResult <= 0)
                        {
                            res.Code = APIEnums.Fail;
                            res.Msg = "住院登记创建失败";
                            logger.LogError("住院登记创建失败，SaveChanges返回0");
                            return Task.FromResult(res);
                        }

                        logger.LogInformation($"住院登记创建成功，ID:{inpatientRegistry.Id}");

                        // 2. 更新病床状态
                        var bed = hospitalBedRepository.GetALL()
                            .FirstOrDefault(x => x.Id == request.WardId && x.IsDeleted == false);

                        if (bed != null)
                        {
                            bed.HospitalBedStatus = 1; // 设置为已占用
                            bed.CurrentMedicalCard = request.MedicalCard;
                            
                            var bedUpdateResult = hospitalBedRepository.Update(bed);
                            
                            if (bedUpdateResult <= 0)
                            {
                                res.Code = APIEnums.Fail;
                                res.Msg = "病床状态更新失败";
                                logger.LogError("病床状态更新失败");
                                return Task.FromResult(res);
                            }

                            logger.LogInformation($"病床状态更新成功，病床ID:{bed.Id}");
                        }

                        // 3. 更新病房使用情况
                        var room = hospitalRoomRepository.GetALL()
                            .FirstOrDefault(x => x.Id == request.WardNo && x.IsDeleted == false);

                        if (room != null)
                        {
                            room.Bed_occupied += 1; // 病床使用数+1
                            
                            var roomUpdateResult = hospitalRoomRepository.Update(room);
                            
                            if (roomUpdateResult <= 0)
                            {
                                res.Code = APIEnums.Fail;
                                res.Msg = "病房使用情况更新失败";
                                logger.LogError("病房使用情况更新失败");
                                return Task.FromResult(res);
                            }

                            logger.LogInformation($"病房使用情况更新成功，病房ID:{room.Id}，当前使用数:{room.Bed_occupied}");
                        }

                        // 提交事务
                        transaction.Complete();

                        res.Data = registryResult;
                        res.Code = APIEnums.Success;
                        res.Msg = "住院登记创建成功";
                        logger.LogInformation($"住院登记创建成功，ID:{inpatientRegistry.Id}");
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "创建住院登记时发生异常");
                        res.Code = APIEnums.Fail;
                        res.Msg = "创建住院登记失败";
                        return Task.FromResult(res);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建住院登记时发生异常");
                res.Code = APIEnums.Fail;
                res.Msg = "创建住院登记失败";
            }

            return Task.FromResult(res);
        }

        /// <summary>
        /// 验证请求参数
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private ValidationResult ValidateRequest(CreateInpatientRegistryCommand request)
        {
            // 验证必填字段
            if (string.IsNullOrWhiteSpace(request.MedicalCard))
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "病人卡号不能为空" };
            }

            if (request.DepartmentId <= 0)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "科室ID无效" };
            }

            if (request.WardNo <= 0)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "病房ID无效" };
            }

            if (request.WardId <= 0)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "病床ID无效" };
            }

            if (request.AdvancePayment < 0)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "预交费不能为负数" };
            }

            if (string.IsNullOrWhiteSpace(request.DiseaseDescription))
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "病情描述不能为空" };
            }

            // 验证病床是否可用
            var bed = hospitalBedRepository.GetALL()
                .FirstOrDefault(x => x.Id == request.WardId && x.IsDeleted == false);

            if (bed == null)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "指定的病床不存在" };
            }

            if (bed.HospitalBedStatus != 0) // 0表示空闲
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "指定的病床已被占用或正在维修" };
            }

            // 验证病房是否存在
            var room = hospitalRoomRepository.GetALL()
                .FirstOrDefault(x => x.Id == request.WardNo && x.IsDeleted == false);

            if (room == null)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "指定的病房不存在" };
            }

            // 验证病房是否还有空床位
            if (room.Bed_occupied >= room.Bed_total)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "该病房已满，无法安排新病人" };
            }

            return new ValidationResult { IsValid = true };
        }
    }

    /// <summary>
    /// 验证结果
    /// </summary>
    public class ValidationResult
    {
        public bool IsValid { get; set; }
        public string ErrorMessage { get; set; } = string.Empty;
    }
}
